package com.pay.ioopos.fragment;

import com.pay.ioopos.DataFactory;
import com.pay.ioopos.DataStore;
import com.pay.ioopos.HttpUtil;
import com.pay.ioopos.Utils;

import org.json.JSONObject;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Date;

public class PayIngFragment extends PayIngAbstract {
    private String orderNo;
    public PayIngFragment(PayFinishListener listener, String barcode, String amount) {
        super(listener, barcode, amount);
    }

    public String getOrderNo() {
        return orderNo;
    }

    @Override
    public void execute() throws Exception {
        super.execute();
        String amount = new BigDecimal(this.amount).multiply(new BigDecimal("100")).setScale(0, RoundingMode.DOWN).toPlainString();
        DataStore store = DataFactory.getDataStore();
        final String transKey = store.getTransKey();
        final String serverUrl = store.getServerUrl();
        final String sn = Utils.sn();
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String sign = Utils.sha256(barcode + sn + timestamp + transKey);
        JSONObject json = new JSONObject();
        json.put("version", "v2");
        json.put("payCode", barcode);
        json.put("amount", amount);
        json.put("deviceSn", sn);
        json.put("timestamp", timestamp);
        json.put("sign", sign);
        String jsonString = json.toString();
        jsonString = HttpUtil.post(serverUrl + "/qrpos/api/mch/trade/create", jsonString);

        json = new JSONObject(jsonString);
        if (!json.getString("status").equals("200")) {
            showToast("["+ json.getString("status") +"]" + json.getString("message"));
            showPayFail();
            return;
        }
        JSONObject result = json.getJSONObject("result");
        orderNo = result.getString("payNo");
        String channelOrderNo = null;
        if (result.has("thirdTradeNo")) {
            channelOrderNo = result.getString("thirdTradeNo");
        }
        String status = result.getString("status");
        switch (status) {
            case "INIT_FAIL":
            case "CLOSED":
                showPayFail();
                break;
            case "SUCCESS":
            case "FINISHED":
                showPaySuccess(orderNo, channelOrderNo);
                break;
            default:
                query(orderNo, channelOrderNo);
                break;
        }

    }

    private void query(String orderNo, String channelOrderNo) throws Exception {
        int i = 0;
        while(true) {
            Thread.sleep(3000);
            boolean end = query(orderNo, (no, st) -> {
                switch (st) {
                    case "CLOSED":
                        showPayFail();
                        return true;
                    case "SUCCESS":
                    case "FINISHED":
                        showPaySuccess(orderNo, channelOrderNo);
                        return true;
                }
                return false;
            });
            if (end) {
                break;
            }
            i++;
            if (i>=5) {
                showPayExpired();
                break;
            }
        }
    }

    private boolean query(String orderNo, QueryCallback callback) throws Exception {
        DataStore store = DataFactory.getDataStore();
        final String transKey = store.getTransKey();
        final String serverUrl = store.getServerUrl();
        final String sn = Utils.sn();
        String timestamp = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date());
        String sign = Utils.sha256(orderNo + sn + timestamp + transKey);
        JSONObject json = new JSONObject();
        json.put("version", "v2");
        json.put("payNo", orderNo);
        json.put("deviceSn", sn);
        json.put("timestamp", timestamp);
        json.put("sign", sign);
        String jsonString = json.toString();
        jsonString = HttpUtil.post(serverUrl + "/qrpos/api/mch/trade/status", jsonString);
        json = new JSONObject(jsonString);
        if (!json.getString("status").equals("200")) {
            showToast("订单查询失败：["+ json.getString("status") +"]" + json.getString("message"));
            return false;
        }
        JSONObject result = json.getJSONObject("result");
        orderNo = result.getString("payNo");
        String status = result.getString("status");
        return callback.onStatus(orderNo, status);

    }

    private interface QueryCallback {
        boolean onStatus(String orderNo, String status);
    }

}
